package cn.tml.innermost.user.utils;

import cn.tml.innermost.framework.entity.enums.ResultCode;
import cn.tml.innermost.framework.entity.vo.ResultMessage;
import cn.tml.innermost.framework.exception.ServiceException;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;

@Component
@Slf4j
public class RestTemplateHelper {

    @Resource
    private RestTemplate restTemplate;

    private HttpHeaders getHeader() {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json;charset=UTF-8");
        headers.setContentType(type);
        return headers;
    }

    public void request(String url, HttpMethod type, Object data) {
        HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(data), this.getHeader());
        ResponseEntity<ResultMessage> response = restTemplate.exchange(url, type, entity, ResultMessage.class, String.class);
        isSuccess(response.getBody(), url);
    }

    public <T> T request(Class<T> t, String url, HttpMethod type) throws Exception {
        T obj = (T) Class.forName(t.getName()).getDeclaredConstructor().newInstance();
        HttpEntity<String> entity = new HttpEntity<>(null, null);
        ResponseEntity<ResultMessage> response = restTemplate.exchange(url, HttpMethod.DELETE, entity, ResultMessage.class, String.class);
        if (isSuccess(response.getBody(), url)) {
            HashMap<String, Object> hashMap = (HashMap<String, Object>) response.getBody().getResult();
            String methodName = "";
            for (Field field : t.getFields()) {
                field.setAccessible(true);
                String property = field.getName();
                Object value = hashMap.get(field.getName());
                if (value != null) {
                    methodName = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
                    Method getMethod = t.getMethod(methodName, value.getClass());
                    getMethod.invoke(obj, value);
                }
            }
            return obj;
        } else return null;
    }

    public <T> T request(Class<T> t, String url, HttpMethod type, Object data) {
        try {
            T obj = (T) Class.forName(t.getName()).getDeclaredConstructor().newInstance();
            HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(data), this.getHeader());
            ResponseEntity<ResultMessage> response = restTemplate.exchange(url, type, entity, ResultMessage.class, String.class);
            HashMap<String, Object> hashMap = (HashMap<String, Object>) response.getBody().getResult();
            if (isSuccess(response.getBody(), url)) {
                String methodName = "";
                Object value = "";
                Long v = 0L;
                for (Field field : t.getDeclaredFields()) {
                    field.setAccessible(true);
                    String property = field.getName();
                    Class<?> fieldType = field.getType();
                    value = hashMap.get(property);
                    if (fieldType.getSimpleName().equals("Long")) {
                        v = Long.parseLong(String.valueOf(value));
                        if (value != null) {
                            methodName = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
                            Method getMethod = t.getMethod(methodName, v.getClass());
                            getMethod.invoke(obj, v);
                        }
                    } else {
                        if (value != null) {
                            methodName = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
                            Method getMethod = t.getMethod(methodName, value.getClass());
                            getMethod.invoke(obj, value);
                        }
                    }
                }
                return obj;
            } else return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private Boolean isSuccess(ResultMessage body, String url) {
        if (!body.isSuccess()) {
            log.error("发送请求失败,目标地址为" + url);
            log.error("返回错误信息" + body.getResult());
            throw new ServiceException(ResultCode.API_Error);
        }
        return true;


    }

}
